import java.util.Arrays;

public class test {
    // 递归解决汉诺塔问题

    public static void main1(String[] args) {
        haNo(1, 'A', 'B', 'C');
        System.out.println();
        haNo(2, 'A', 'B', 'C');
        System.out.println();
        haNo(3, 'A', 'B', 'C');
        System.out.println();

    }

    public static void move(char pos1, char pos2) {
        System.out.print(pos1 + "=>" + pos2 + " ");
    }

    /**
     * @param n     总共有多少盘子
     * @param pos_s 起始位置
     * @param pos_p 中转位置
     * @param pos_e 目的位置
     */
    public static void haNo(int n, char pos_s, char pos_p, char pos_e) {
        // 终止条件
        if (n == 1) {
            move(pos_s, pos_e);
            return;
        }
        haNo(n - 1, pos_s, pos_e, pos_p);
        move(pos_s, pos_e);
        haNo(n - 1, pos_p, pos_s, pos_e);
    }

    //实现一个方法 transform, 以数组为参数, 循环将数组中的每个元素乘以 2 , 并设置到对应的数组元素上. 例如 原数组为 {1, 2, 3}, 修改之后为 {2, 4, 6}
    public static void main2(String[] args) {
        int[] array1 = {1, 23, 4, 5};
        func1(array1);
//        for (int i = 0; i < array1.length; i++) {
//            System.out.print(" " + array1[i] + " ");
//        }
        System.out.println(Arrays.toString(array1));
    }

    public static void func1(int[] array) {
        for (int i = 0; i < array.length; i++) {
            array[i] = array[i] * 2;
        }
    }

    // 调整数组顺序使得奇数位于偶数之前。调整之后，不关心大小顺序。
    //如数组：[1,2,3,4,5,6]
    //调整后可能是：[1, 5, 3, 4, 2, 6]
    public static void main3(String[] args) {
        int[] array1 = {1, 3, 7, 5};
        trans(array1);
        System.out.println(Arrays.toString(array1));

    }

    public static void trans(int[] array) {
        int i = 0;
        int j = array.length - 1;
//        while (i < j) {
//            // 如果i对应的元素是奇数，下标继续后移 即找到第一个偶数下标的会停
//            while (i < j && array[i] % 2 != 0) {
//                i++;
//            }
//            // 如果j对应的元素是偶数，下标继续前移 即找到第一个奇数下标的会停
//            while (i < j && array[j] % 2 == 0) {
//                j--;
//            }
//            int tmp = array[i];
//            array[i] = array[j];
//            array[j] = tmp;
//        }
        // 如果i对应的元素是奇数，下标继续后移 即找到第一个偶数下标的会停
        while (i < j && array[i] % 2 != 0) {
            i++;
        }
        // 如果j对应的元素是偶数，下标继续前移 即找到第一个奇数下标的会停
        while (i < j && array[j] % 2 == 0) {
            j--;
        }
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

    // 给定一个有序整型数组, 实现二分查找
    // 二分查找一定是建立在有序的情况下

    public static void main4(String[] args) {
        int[] array = {1, 2, 3, 4, 5, 6};
        System.out.println(binarySearch(array, 2));
        System.out.println(Arrays.binarySearch(array, 2));

    }

    public static int binarySearch(int[] array, int key) {
        int i = 0;
        int j = array.length - 1;
        // 注意这个等号
        while (i <= j) {
            int mid = (i + j) / 2;
            if (array[mid] < key) {
                i = mid + 1;
            } else if (array[mid] == key) {
                return mid;
            } else {
                j = mid - 1;
            }
        }
        return -1;
    }

    //给定一个整数数组 nums 和一个整数目标值 target，请你在该数组中找出和为目标值target的那两个整数，并返回它们的数组下标。
    //你可以假设每种输入只会对应一个答案。但是，数组中同一个元素在答案里不能重复出现。
    //你可以按任意顺序返回答案。
    //示例 1：
    //输入：nums = [2,7,11,15], target = 9
    //
    //输出：[0,1]
    //
    //解释：因为 nums[0] + nums[1] == 9 ，返回 [0, 1] 。

    public static void main5(String[] args) {
        int[] array = {2, 4, 6, 3};
        int[] ret = find(array, 7);
        System.out.println(Arrays.toString(ret));

    }

    public static int[] find(int[] array, int target) {
        int[] ret = {-1, -1};
        for (int i = 0; i < array.length; i++) {
            for (int j = i + 1; j < array.length; j++) {
                if (array[i] + array[j] == target) {
//                    return new int[]{i, j};
                    ret[0] = i;
                    ret[1] = j;
                }

            }
        }
        return ret;
    }


    // 给定一个非空整数数组，除了某个元素只出现一次以外，其余每个元素均出现两次。找出那个只出现了一次的元素。
    // 输入: [4,1,2,1,2]
    // 输出: 4
    // 使用异或，如果两个值相同则为0，不相同则为1 ;0和任何数异或都等于那个数
    public static void main6(String[] args) {
        int[] array = {4, 1, 2, 1, 2};
        System.out.println(func6(array));
    }

    public static int func6(int[] array) {
        int ret = 0;
        for (int i = 0; i < array.length; i++) {
            ret ^= array[i];
        }
        return ret;
    }

    //给定一个大小为 n 的数组，找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
    //你可以假设数组是非空的，并且给定的数组总是存在多数元素。
    //输入：[2,2,1,1,1,2,2]
    //输出：2
    public static void main7(String[] args) {
        int[] array = {2, 2, 1, 1, 1, 2, 2};
        System.out.println(func7(array));
    }

    public static int func7(int[] array) {
        Arrays.sort(array);
        return array[array.length / 2];
    }
    // 摩尔投票法
//    public

    //给你一个整数数组 arr，请你判断数组中是否存在连续三个元素都是奇数的情况：如果存在，请返回 true ；否则，返回 false 。
    //示例 1：
    //输入：arr = [2,6,4,1]
    //输出：false
    //解释：不存在连续三个元素都是奇数的情况。
    //示例 2：
    //输入：arr = [1,2,34,3,4,5,7,23,12]
    //输出：true
    //解释：存在连续三个元素都是奇数的情况，即 [5,7,23] 。

    public static void main(String[] args) {
        int[] array = {1, 2, 34, 3, 4, 5, 7, 23, 12};
        System.out.println(func8(array));
    }

    public static boolean func8(int[] array) {
        int count = 0;
        for (int i = 0; i < array.length; i++) {
            if (array[i] % 2 != 0) {
                count++;
                if (count == 3) {
                    return true;
                }
            } else {
                count = 0; // 一定得置0，才能证明是连续的
            }
        }
        return false;
    }
}
